"""
Sample pybookshelf plugin, process TXT files.
"""
import os.path
import gtk
import subprocess

from pybs.plugin import construct_attr as ca
from pybs.strunicode import str2unicode
from pybs import html
from pybs import collection
from pybs import settings

PLUGIN_NAME = _("Plain TXT plugin")
PLUGIN_SUPPORTED_FILE_TYPES = ("txt",)

# Callback functions. They all are required.

def extract_metadata(filepath):
    """
    Extracts metadata from the file
    
    @param filepath: full path to the file
    @return: list of metadata elements
    """
    metadata = []
    metadata.append(ca("author", "Unknown author of TXT file"))
    
    # extract title from filename
    (head, tail) = os.path.split(filepath)
    # remove suffix (".txt"), kindof hack
    title = tail[:-4]
    # we cannot just pass title because it's encoded in filesystem encoding
    # but pybookshelf operates unicode strings
    title = str2unicode(title)
    # TODO: we also must process possible unicode exception from str2unicode() call

    metadata.append(ca("title", title))

    return metadata

def preferences_glade_root():
    """
    Return glade object that corresponds to root of preferences window
    
    @return: gtk.glade.XML instance or None if plugin doesn't provide its own tab on 
             preferences screen
    """
    xml = gtk.glade.xml_new_from_buffer(glade_xml_buffer, len(glade_xml_buffer), 
        root="preferences_widget", domain="pybookshelf");
    return xml

def preferences_init_widgets_values(xml):
    """
    Callback function, initializes widgets on the corresponding prefernces tab
    
    @param xml: gtk.glade.XML instance from previous preferences_glade_root() call
    """
    viewer = settings.get_str("external_viewer", plugin="txt")
    xml.get_widget("txt_viewer_text_entry").set_text(viewer)
    
def preferences_remember_widget_values(xml):
    """
    Callback function, remember values of widgets on the corresponding preferences tab
    
    @param xml: gtk.glade.XML instance from previous preferences_glade_root() call
    """
    viewer = xml.get_widget("txt_viewer_text_entry").get_text()
    settings.set_str("external_viewer", viewer, plugin="txt")

def read_book(book_path, parent_window):
    """
    Callback function, called when user is going to "read the book". In this function we should 
    do something to display the book: open external program for example.

    @param book_path: path to book file
    @param parent_window: parent window, gtk.Window instance
    @return: list of generated files (including images, styles etc), or 
        subprocess.Popen instance of launched application, or
        None if nothing was done
    """
    viewer = settings.get_str("external_viewer", plugin="txt")
    if viewer == "":
        return
    
    result = None
    
    try:
        p = subprocess.Popen([viewer, book_path])
        result = p
    except OSError, e:
        log.error("read_book() failed, OSError: %s" % e)
    
    return result

def can_edit_book(book_path):
    """
    Callback function, tells caller is plugin supports book file editing.
    
    @return: True if plugin supports book file editing, False otherwise
    """
    return False

def gen_book_html(file_id, temp_files_dir, presets=None):
    """
    Generate HTML page that represents the given book. This page will be displayed
    when user open book page.
    
    @param file_id: book file id in the collection database
    @param temp_files_dir: path to directory where temporary files (e.g. generated images)
                           should be placed
    @param presets: dict with predefined values, function must merge them with generated ones
                    usually contains just 'rating' element
    @return: tuple (body, files, book_title), where body is generated html-code,
             files is a list of full paths of generated files (e.g. images), 
             book_title is a book title, extracted from the file or from metadata
    """
    page_template = html.get_html_template("book")
    author_template = html.get_html_template("book_author")
    genre_template = html.get_html_template("book_genre")
    series_template = html.get_html_template("book_series")

    metadata = collection.get_book_metadata(file_id)
    
    authors_list = []
    genres_list = []
    series = []
    title = ""
    
    for m in metadata:
        try:
            if m['attr_name'] == "author":
                authors_list.append(author_template % {
                    #'author_id': m['attr_value_id'],
                    'author_name': m['attr_value']
                    })
                continue
            
            if m['attr_name'] == "genre":
                match = ""
                
                for param_name, param_value in m['attr_params']:
                    if param_name == "match" and str(param_value) != "100":
                        match = " (%s%%)" % param_value
                    
                genres_list.append(genre_template % {
                    'genre_name': m['attr_value'], # nontranslated genre name
                    'title': genres.expand_genre(m['attr_value']),
                    'match': match
                    #'num_books': number
                    })
                continue
            
            if m['attr_name'] == "sequence":
                for param_name, param_value in m['attr_params']:
                    if param_name != "number":
                        continue

                    try:
                        number = int(param_value)
                    except ValueError:
                        number = 0
                    except TypeError:
                        number = 0
                        
                    if number != 0:
                        number = " (%s)" % number
                    else:
                        number = ""
                    
                    series.append(series_template % {
                        'series_name': m['attr_value'],
                        'title': m['attr_value'] + number
                        })
                continue
            
            if m['attr_name'] == "title":
                title = m['attr_value']
                continue
            
        except KeyError, e:
            log.error("Metadata key error: %s" % e)
            log.error(traceback.format_exc())
    
    authors_list = ", ".join(authors_list)
    genres_list = ", ".join(genres_list)
    
    annotation = _("<i>No annotation available.</i>")
    
    sequences = ""
    if len(series):
        sequences = _("Series: ") + ", ".join(series)
    
    presets.update({
        'title': title,
        'authors': authors_list,
        'genres': genres_list,
        'annotation': annotation,
        'covers': '',
        'file_id': file_id,
        'icon_download': html.stock_img_url("download.png"),
        'icon_read': html.stock_img_url("read.png"),
        'icon_edit': html.stock_img_url("edit.png"),
        'sequences': sequences,
        'export_tooltip': _("Export book file into external directory"),
        'readbook_tooltip': _("Read book")
        })
    
    body = page_template % presets
        
    return body, [], title

# end of callback functions block

# plugin specific functions and data
glade_xml_buffer = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>                                                                
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">                                                                     
<glade-interface>                                                                                                     
  <widget class="GtkWindow" id="window1">
    <child>
      <widget class="GtkVBox" id="preferences_widget">
        <property name="visible">True</property>
        <child>
          <widget class="GtkHBox" id="hbox5">
            <property name="visible">True</property>
            <child>
              <widget class="GtkLabel" id="label4">
                <property name="visible">True</property>
                <property name="xalign">0</property>
                <property name="xpad">2</property>
                <property name="label" translatable="yes">External viewer:</property>
                <property name="single_line_mode">True</property>
              </widget>
              <packing>
                <property name="expand">False</property>
              </packing>
            </child>
            <child>
              <widget class="GtkEntry" id="txt_viewer_text_entry">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
              </widget>
              <packing>
                <property name="position">1</property>
              </packing>
            </child>
          </widget>
          <packing>
            <property name="expand">False</property>
          </packing>
        </child>
        <child>
          <placeholder/>
        </child>
      </widget>
    </child>
  </widget>
</glade-interface>
'''


